package service

import (
	"fmt"
	"go-project/common"
	"go-project/common/casbininit"
	"go-project/dto/requrest"
	"go-project/models"
	"strconv"
	"strings"
)

type Roles struct {
}

func (t Roles) FindLists(rolesSearchRequest *requrest.RolesSearchRequest) (lists []models.Roles, count int64, err error) {
	offset := (rolesSearchRequest.Pagination.Page - 1) * rolesSearchRequest.Pagination.Limit
	var roles *models.Roles
	query := common.DB.Table(roles.TableName())
	if len(rolesSearchRequest.Name) > 0 {
		query = query.Where("name like ?", fmt.Sprintf("%%%s%%", rolesSearchRequest.Name))
	}
	query.Model(roles).Select("count(id)").Count(&count)
	err = query.Limit(rolesSearchRequest.Pagination.Limit).Order("id desc").Offset(offset).Find(&lists).Error
	rolesSearchRequest.Pagination.GetPageCount(count)
	return
}

func (Roles) Add(request *requrest.RolesSInsertRequest) (uint, error) {
	// 开始事务
	tx := common.DB.Begin()
	defer func() {
		if r := recover(); r != nil {
			tx.Rollback()
		}
	}()
	if err := tx.Error; err != nil {
		return 0, err
	}
	var roles models.Roles
	request.Generate(&roles)
	result := common.DB.Create(&roles)
	if err := result.Error; err != nil {
		tx.Rollback()
		return 0, err
	}
	PermissionsIds := strings.Split(request.PermissionsId, ",")
	var permissions *models.Permissions
	var lists []models.Permissions
	common.DB.Model(permissions).Where(PermissionsIds).Find(&lists)
	for _, id := range PermissionsIds {
		atoi, _ := strconv.Atoi(id)
		err := permissions.GetChildrenPermissions(uint(atoi), &lists)
		if err != nil {
			tx.Rollback()
			return 0, err
		}
	}
	//查询该角色对于的所有权限
	role := casbininit.Enforcer.GetPermissionsForUser("role:" + roles.Key)

	if len(role) > 0 {
		//删除该角色对于的所有权限
		_, err := casbininit.Enforcer.DeletePermissionsForUser("role:" + roles.Key)
		if err != nil {
			tx.Rollback()
			return 0, err
		}
	}
	var permissionss = make([][]string, 0, 10)
	for _, list := range lists {
		var permission []string
		permission = append(permission, list.Code, list.Action)
		permissionss = append(permissionss, permission)
	}
	for i := 0; i < len(permissionss); i++ {
		_, err := casbininit.Enforcer.AddPermissionsForUser("role:"+roles.Key, permissionss[i])
		if err != nil {
			tx.Rollback()
			return 0, nil
		}
	}
	return roles.ID, tx.Commit().Error
}

func (Roles) Update(request *requrest.RolesUpdateRequest) (uint, error) {
	// 开始事务
	tx := common.DB.Begin()
	defer func() {
		if r := recover(); r != nil {
			tx.Rollback()
		}
	}()
	if err := tx.Error; err != nil {
		return 0, err
	}
	var model models.Roles
	row := common.DB.First(&model, request.ID)
	if row.Error != nil {
		tx.Rollback()
		return 0, row.Error
	}
	request.Generate(&model)
	result := common.DB.Save(&model)
	if err := result.Error; err != nil {
		tx.Rollback()
		return 0, err
	}
	PermissionsIds := strings.Split(request.PermissionsId, ",")
	var permissions *models.Permissions
	var lists []models.Permissions
	common.DB.Model(permissions).Where(PermissionsIds).Find(&lists)
	for _, id := range PermissionsIds {
		atoi, _ := strconv.Atoi(id)
		err := permissions.GetChildrenPermissions(uint(atoi), &lists)
		if err != nil {
			tx.Rollback()
			return 0, err
		}
	}
	//查询该角色对于的所有权限
	role := casbininit.Enforcer.GetPermissionsForUser("role:" + model.Key)

	if len(role) > 0 {
		//删除该角色对于的所有权限
		_, err := casbininit.Enforcer.DeletePermissionsForUser("role:" + model.Key)
		if err != nil {
			tx.Rollback()
			return 0, err
		}
	}
	var permissionss = make([][]string, 0, 10)
	for _, list := range lists {
		var permission []string
		permission = append(permission, list.Code, list.Action)
		permissionss = append(permissionss, permission)
	}
	for i := 0; i < len(permissionss); i++ {
		_, err := casbininit.Enforcer.AddPermissionsForUser("role:"+model.Key, permissionss[i])
		if err != nil {
			tx.Rollback()
			return 0, nil
		}
	}
	return model.ID, tx.Commit().Error

}

func (Roles) Del(id uint) (uint, error) {
	// 开始事务
	tx := common.DB.Begin()
	defer func() {
		if r := recover(); r != nil {
			tx.Rollback()
		}
	}()
	if err := tx.Error; err != nil {
		return 0, err
	}
	var model models.Roles
	result := common.DB.First(&model, id)
	if err := result.Error; err != nil {
		tx.Rollback()
		return 0, err
	}
	result = common.DB.Delete(&model, id)
	if err := result.Error; err != nil {
		tx.Rollback()
		return 0, err
	}
	_, err := casbininit.Enforcer.DeletePermissionsForUser("role:" + model.Key)
	if err != nil {
		tx.Rollback()
		return 0, err
	}
	return uint(result.RowsAffected), tx.Commit().Error
}
func (Roles) Get(id uint) (models.Roles, error) {
	var model models.Roles
	result := common.DB.First(&model, id)
	return model, result.Error
}

func (Roles) BatchDelByIds(ids []int) (uint, error) {
	// 开始事务
	tx := common.DB.Begin()
	defer func() {
		if r := recover(); r != nil {
			tx.Rollback()
		}
	}()
	if err := tx.Error; err != nil {
		return 0, err
	}
	var model models.Roles
	var RolesModels []models.Roles
	result := common.DB.Model(&model).Find(&RolesModels, ids)
	if err := result.Error; err != nil {
		tx.Rollback()
		return 0, err
	}
	result = common.DB.Delete(&model, ids)
	if err := result.Error; err != nil {
		tx.Rollback()
		return 0, err
	}
	for _, rolesModel := range RolesModels {
		_, err := casbininit.Enforcer.DeletePermissionsForUser("role:" + rolesModel.Key)
		if err != nil {
			tx.Rollback()
			return 0, err
		}
	}
	return uint(result.RowsAffected), tx.Commit().Error
}

func (Roles) DistributePermissions(request *requrest.RolesAuthPerMissionsRequest) error {
	var roles models.Roles
	first := common.DB.First(&roles, request.ID)
	if err := first.Error; err != nil {
		return err
	}

	PermissionsIds := strings.Split(request.PermissionsId, ",")
	var permissions *models.Permissions
	var lists []models.Permissions
	common.DB.Model(permissions).Where(PermissionsIds).Find(&lists)
	for _, id := range PermissionsIds {
		atoi, _ := strconv.Atoi(id)
		err := permissions.GetChildrenPermissions(uint(atoi), &lists)
		if err != nil {
			return err
		}
	}
	//查询该角色对于的所有权限
	role := casbininit.Enforcer.GetPermissionsForUser("role:" + roles.Key)

	if len(role) > 0 {
		//删除该角色对于的所有权限
		_, err := casbininit.Enforcer.DeletePermissionsForUser("role:" + roles.Key)
		if err != nil {
			return err
		}
	}
	var permissionss = make([][]string, 0, 10)
	for _, list := range lists {
		var permission []string
		permission = append(permission, list.Code, list.Action)
		permissionss = append(permissionss, permission)
	}
	for i := 0; i < len(permissionss); i++ {
		_, err := casbininit.Enforcer.AddPermissionsForUser("role:"+roles.Key, permissionss[i])
		if err != nil {
			return nil
		}
	}
	return nil
}
